/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pl.abstractvoid.gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.HashMap;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import org.scilab.forge.jlatexmath.TeXConstants;
import org.scilab.forge.jlatexmath.TeXFormula;
import org.scilab.forge.jlatexmath.TeXIcon;
import pl.abstractvoid.languages.LanguageProvider;

/**
 * Components responsible for displaying the documentation for a specific 
 * distribution. Currently displayed in LaTeX format. Uses the jlatexmath
 * for generation of the LaTeX document in an image format.
 * @author Wojciech Szałapski
 * @author Ivo Zieliński
 */
public class DistributionHelpDocumentPanel extends javax.swing.JPanel implements DistributionStateObserver {

    private MainFrame mediator;
    /**
     * Document images are mappewd with class names
     */
    private HashMap<String, BufferedImage> docs = new HashMap();
    private int preferredFontSize = 15;

    public DistributionHelpDocumentPanel(MainFrame mediator) {
        this.mediator = mediator;
        initComponents();
        helpDocumentPanel.setBackground(Color.white);
        loadManualDocument();
        updateUI();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        helpPanelScrollPane = new javax.swing.JScrollPane();
        helpDocumentPanel = new javax.swing.JPanel();

        helpDocumentPanel.setFocusable(false);
        helpDocumentPanel.setLayout(new java.awt.BorderLayout());
        helpPanelScrollPane.setViewportView(helpDocumentPanel);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(helpPanelScrollPane)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(helpPanelScrollPane)
        );
    }// </editor-fold>//GEN-END:initComponents
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel helpDocumentPanel;
    private javax.swing.JScrollPane helpPanelScrollPane;
    // End of variables declaration//GEN-END:variables

    /**
     * Ceates and loads help document, corrseponding to the new distribution
     * into the map.
     * @param helpDocument String representing the LateX form of the help
     * document.
     */
    private void loadHelpDocument(String helpDocument) {
        TeXFormula formula = new TeXFormula(helpDocument);
        TeXIcon ti = formula.new TeXIconBuilder().
                setStyle(TeXConstants.STYLE_DISPLAY).
                setSize(preferredFontSize).
                build();
        ti.setInsets(new Insets(5, 5, 5, 5));
        BufferedImage image = new BufferedImage(ti.getIconWidth(), ti
                .getIconHeight(), BufferedImage.TYPE_4BYTE_ABGR);
        if (mediator.getCurrentDistribution() != null) {
            docs.put(mediator.getCurrentDistribution().getClass().getSimpleName() + "_"
                    + LanguageProvider.getInstance().getCurrentLanguageCode(), image);
        }
        ti.paintIcon(new JLabel(), image.getGraphics(), 0, 0);
    }

    /**
     * Returns the mock help document's content.
     * 
     * @return The mock help document's content.
     */
    private String getMockContent() {
        return "\\text{" + LanguageProvider.getInstance().getString("unableToReadHelp") + "}";
    }
    
    /**
     * Loads mock help document.
     */
    private void loadMockDocument() {
        loadHelpDocument(getMockContent());
    }

    /**
     * Loads the manual document and displays it.
     */
    private void loadManualDocument() {
        TeXFormula formula;
        try {
            formula = new TeXFormula(UtilsGUI.readFile("/Documents/Manual_"
                    + LanguageProvider.getInstance().getCurrentLanguageCode() + ".tex"));
        } catch (IOException ex) {
            formula = new TeXFormula(getMockContent());
        }
        TeXIcon ti = formula.createTeXIcon(TeXConstants.STYLE_DISPLAY, preferredFontSize);
        BufferedImage image = new BufferedImage(ti.getIconWidth(), ti.getIconHeight(),
                BufferedImage.TYPE_4BYTE_ABGR);
        JLabel label = new JLabel();
        label.setForeground(new Color(0, 0, 0));
        ti.paintIcon(label, image.createGraphics(), 0, 0);
        helpDocumentPanel.removeAll();
        helpDocumentPanel.add(new JLabel(new ImageIcon(image)));
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                helpPanelScrollPane.getVerticalScrollBar().setValue(0);
                helpPanelScrollPane.getHorizontalScrollBar().setValue(0);
            }
        });
    }

    /**
     * When distribution changes, displayed help documenent is changed to the 
     * one corresponding to the current distribution.
     */
    @Override
    public void distributionChangedNotify() {
        if (mediator.getCurrentDistribution() == null) {
            //Load manual if no distribution was created yet
            loadManualDocument();
        } else if (docs.containsKey(mediator.getCurrentDistribution().getClass().getSimpleName()
                + "_" + LanguageProvider.getInstance().getCurrentLanguageCode())) {
            helpDocumentPanel.removeAll();
            JLabel label = new JLabel(new ImageIcon(docs.get(mediator.getCurrentDistribution().getClass().getSimpleName()
                    + "_" + LanguageProvider.getInstance().getCurrentLanguageCode())), JLabel.LEFT);
            helpDocumentPanel.add(label, BorderLayout.NORTH);
            helpDocumentPanel.repaint();
        } else {
            //Load mock document if current distribution' name is not in the map
            loadMockDocument();
        }
        updateUI();
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                helpPanelScrollPane.getVerticalScrollBar().setValue(0);
            }
        });
    }
    
    /**
     * Generates new document image if it is the first time a distribution
     * was created, and switches the displayed document. Just switches the view
     * if the newly created distribution is already in the map.
     */
    @Override
    public void newDistributionNotify() {
        if (!docs.containsKey(mediator.getCurrentDistribution().getClass().getSimpleName()
                + "_" + LanguageProvider.getInstance().getCurrentLanguageCode())) {
            try {
                String helpDocument = UtilsGUI.readFile(getCurrentDocumentFile());
                loadHelpDocument(helpDocument);
            } catch (IOException ex) {
                loadMockDocument();
            }
        }
        distributionChangedNotify();
    }

    @Override
    public void distributionDeletedNotify(boolean lastInstanceDeleted) {
        if (lastInstanceDeleted) {
            loadManualDocument();
        }
    }

    @Override
    public void distributionsLoadedNotify() {
    }

    /**
     * Returns current help document file path based on the current
     * distribution.
     * <p>
     * The path is relative to package's resource folder.
     *
     * @return Path of the LaTeX help document file appropriate for the current
     * distribution or null if there is no current distribution.
     */
    public String getCurrentDocumentFile() {
        if (mediator.getCurrentDistribution() == null) {
            return null;
        }
        return "/Documents/" + mediator.getCurrentDistribution().getClass().getSimpleName()
                + "_" + LanguageProvider.getInstance().getCurrentLanguageCode() + ".tex";
    }
}
